home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus Leser 15 / Amiga Plus Leser CD 15.iso / Tools / Freeware / CharMap / Sources / cmap.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-03-13  |  18.8 KB  |  572 lines

  1. /****************************************************************
  2. ** charmap.c : Display an ASCII table of a given Amiga font.   **
  3. **             Written (mainly) by T.Pierron                   **
  4. **             11-Dec-1999                                     **
  5. **-------------------------------------------------------------**
  6. ** Special Requirements: WorkBench 2.0, version 36 or above    **
  7. ****************************************************************/
  8.  
  9. #include <intuition/intuition.h>
  10. #include <intuition/intuitionbase.h>
  11. #include <graphics/rastport.h>
  12. #include <graphics/gfxmacros.h>
  13. #include <graphics/text.h>
  14. #include <libraries/gadtools.h>
  15. #include <intuition/screens.h>
  16.  
  17. #include "cmap.h"
  18. #define  CATCOMP_NUMBERS        /* We will need the string id */
  19. #define  CATCOMP_STRINGS        /* and the english string corresponding to the id */
  20. #include "cmap_strings.h"
  21.  
  22. /* Shared libraries we'll need to open */
  23. struct IntuitionBase *IntuitionBase = NULL;
  24. struct GfxBase *GfxBase       = NULL;
  25. struct Library *GadToolsBase  = NULL;
  26. struct Library *AslBase       = NULL;
  27. struct Library *DiskfontBase  = NULL;
  28. struct Library *CxBase            = NULL;
  29. struct Library *IconBase        = NULL;
  30. struct Library *KeymapBase        = NULL;
  31. struct Library *LocaleBase    = NULL;
  32. struct Library *UtilityBase   = NULL;
  33. void           *clipdev            = NULL;
  34.  
  35. /* Graphics area: */
  36. struct RastPort *RP,RPT;
  37. struct TextFont *font,*newfont=0;
  38.  
  39. struct Menu   *menu   = NULL;                /* Menu attached to the window */
  40. struct Screen *screen = NULL;                /* Screen where window will be opened */
  41. struct Window *window = NULL;                /* Main window ptr */
  42. struct Gadget *glist  = NULL;             /* Gadget list pointer */
  43. struct Gadget *gad;                            /* our running Gadget pointer */
  44. struct Gadget *copy_gad, *paste_gad;    /* Copy and paste gadget (for menu action) */
  45. void   *vi = NULL;                            /* VisualInfo pointer */
  46.  
  47. WORD  ZoomData[4];                            /* Position of iconified window */
  48. WORD  xdeb,ydeb,xfin,yfin,X,Y;            /* Position of ASCII table */
  49. UBYTE CharWid[256],Char[]=" ";            /* Data of ASCII table */
  50. UBYTE Font_height;                            /* Font information */
  51. UBYTE GadDisable=0;                            /* If a ressource is unavailable */
  52. UBYTE Layout;                                    /* Types of layout */
  53. UBYTE VertSort=1;                                /* TRUE if chars are sorted vertically first */
  54. WORD  Wid[6];                                    /* Width of various gadgets */
  55.  
  56. /* For the "version" command */
  57. const UBYTE VERSION[]= "$VER:CharMap v" CHARMAP_VERSION " " CHARMAP_DATE "\n";
  58.  
  59. /* Tag list for opening the main window: */
  60. ULONG WinTags[] = {
  61.     WA_Zoom,(ULONG)ZoomData,
  62.     WA_NewLookMenus,TRUE,
  63.     TAG_DONE
  64. };
  65.  
  66. /* Set the color of the menu to Newlook (only 3.0+) */
  67. ULONG MenuTags[] = {
  68.     GTMN_FrontPen, 1,
  69.     TAG_DONE
  70. };
  71.  
  72. ULONG BoxTags[] = {
  73.     GT_VisualInfo,0,
  74.     TAG_DONE,FALSE,
  75.     TAG_DONE
  76. };
  77.  
  78. /* Our gadtools gadget text */
  79. UBYTE *GadTxt[7+NUM_CHARSET+5]={
  80.     "<=",0,0,
  81.     /* MSG_FONTTYPE_STR      **
  82.     ** MSG_MENUCHARSET_STR   */
  83.     MSG_COPY_STR,
  84.     MSG_PASTE_STR,
  85.     MSG_STRGAD_STR,0,0,0,
  86.     /* MSG_MENUASCII8_STR    **
  87.     ** MSG_MENUISOLATIN1_STR **
  88.     ** MSG_MENUSTDAMIGA_STR  */
  89.     NULL,
  90.     MSG_NEWFONT_STR    /* GT **
  91.     ** MSG_MENUFONTSCREEN_ST **
  92.     ** MSG_MENUTEXTFONT_STR  **
  93.     ** MSG_MENUCUSTOMFONT_ST */
  94. };
  95.  
  96. #define    CBLen        Wid[0]            /* "Paste" */
  97. #define    ChrLen    Wid[1]            /* "Charset" */
  98. #define    FtLen        Wid[2]            /* "Font" */
  99. #define    VaLen        Wid[3]            /* Various */
  100. #define    CyCLen    Wid[4]            /* Charset cycle gadget */
  101. #define    CyFLen    Wid[5]            /* Font type cycle gadget */
  102.  
  103. /* Tags associated with the charset cycle gadget */
  104. ULONG CycleTags[]={
  105.     GTCY_Labels, (ULONG) &GadTxt[6],
  106.     GTCY_Active, 1,
  107.     TAG_DONE
  108. };
  109.  
  110. /* The ones associated with the font type */
  111. ULONG FontTags[]={
  112.     GTCY_Labels, (ULONG) &GadTxt[GT+1],
  113.     GTCY_Active, 0,
  114.     TAG_DONE
  115. };
  116.  
  117. /* here we declare the information for our new window - notice that GadTools
  118.  * provides some constants which describe which IDCMP events the Window will
  119.  * need to handle the GadTools Gadgets properly. Just OR them into your
  120.  * normal IDCMPFlags field.
  121.  */
  122.  
  123. ULONG sigwin=0;
  124. struct NewWindow new_window = {
  125.     50, 20, 510, 150,
  126.     ~0, ~0,                        /* DetailPen, BlockPen */
  127.     CLOSEWINDOW | REFRESHWINDOW | MOUSEBUTTONS | MOUSEMOVE | RAWKEY | MENUPICK | MENUVERIFY | GADGETUP,
  128.     ACTIVATE | WINDOWDRAG | WINDOWDEPTH | WINDOWCLOSE | SMART_REFRESH | REPORTMOUSE,
  129.     NULL,                            /* FirstGadget */
  130.     NULL,                            /* CheckMark */
  131.     NULL,                            /* Title */
  132.     NULL,                            /* Screen */
  133.     NULL,                            /* BitMap */
  134.     0, 0, 0, 0,                    /* min/max sizes */
  135.     CUSTOMSCREEN
  136. };
  137.  
  138. /* Error messages */
  139. UBYTE *Errors[]= {
  140.     MSG_BADOS_STR,
  141.     MSG_SCREENLOCK_STR,
  142.     MSG_ERRLAYOUT_STR,
  143.     MSG_FONTREALLYBIG_STR,
  144.     MSG_ERRGADGET_STR,
  145.     MSG_ERRNOMEM_STR,
  146.     MSG_NOASL_STR,
  147.     MSG_NEXTSCR_STR,            /* When commo is not present */
  148.     MSG_KSNOTFOUND_STR
  149. };
  150.  
  151. struct EasyStruct Request= {
  152.     sizeof(struct EasyStruct),0,
  153.     MSG_ABOUT_STR,
  154.     MSG_ABOUTMSG_STR,
  155.     MSG_CONTINUE_STR
  156. };
  157.  
  158. /**********************************************************
  159. *****                    MENU DATA MANAGMENT:                        *****
  160. **********************************************************/
  161.  
  162. /* NewMenu menu declaration */
  163. struct NewMenu newmenu[] =
  164. {
  165.     {NM_TITLE, MSG_MENUTITLE_STR,0 , 0, 0, 0},
  166.     {  NM_ITEM, MSG_FONTTYPE_STR, 0, 0, 0, 0},
  167.     {   NM_SUB,   MSG_MENUFONTSCREEN_STR,"S", CHECKIT|CHECKED, ~1, (APTR) 111},
  168.     {   NM_SUB,   MSG_MENUTEXTFONT_STR,  "T", CHECKIT, ~2, (APTR)112},
  169.     {   NM_SUB,   MSG_MENUCUSTOMFONT_STR,"F", CHECKIT, ~4, (APTR)113},
  170.     {  NM_ITEM, MSG_MENUCHARSET_STR,   0, 0, 0, 0},
  171.     {   NM_SUB,   MSG_MENUASCII8_STR,    "1", CHECKIT, ~1, (APTR)141},
  172.     {   NM_SUB,   MSG_MENUISOLATIN1_STR, "2", CHECKIT, ~2, (APTR)142},
  173.     {   NM_SUB,   MSG_MENUSTDAMIGA_STR,  "3", CHECKIT, ~4, (APTR)143},
  174.     {  NM_ITEM, NM_BARLABEL,  0, 0, 0, 0},
  175.     {  NM_ITEM, MSG_MENUABOUT_STR,       "?", 0, 0, (APTR)15},
  176.     {  NM_ITEM, NM_BARLABEL,  0, 0,  0, 0},
  177.     {  NM_ITEM, MSG_MENUICONOFY_STR,     "I", 0, 0, (APTR)16},
  178.     {  NM_ITEM, MSG_MENUHIDE_STR,        "H", 0, 0, (APTR)17},
  179.     {  NM_ITEM, MSG_MENUQUIT_STR,        "Q", 0, 0, (APTR)18},
  180.  
  181.     {NM_TITLE, MSG_EDITMENU_STR ,0, 0, 0, 0},
  182.     {  NM_ITEM, MSG_CUT_STR,             "X", 0, 0, (APTR)21},
  183.     {  NM_ITEM, NM_BARLABEL,             "C", 0, 0, (APTR)22},
  184.     {  NM_ITEM, NM_BARLABEL,             "V", 0, 0, (APTR)23},
  185.     {  NM_ITEM, NM_BARLABEL,  0, 0,  0, 0},
  186.     {  NM_ITEM, MSG_MENUCLEARTXT_STR,  "Del", NM_COMMANDSTRING, 0, (APTR)24},
  187.     {  NM_ITEM, MSG_MENUSORT_STR,      "Tab", NM_COMMANDSTRING|CHECKIT|MENUTOGGLE, 0, (APTR)26},
  188. /*    {  NM_ITEM, NM_BARLABEL,  0, 0,  0, 0},
  189.     {  NM_ITEM, MSG_SAVESETTINGS,          0, 0,  0, (APTR)27},
  190. */    {NM_END, 0, 0, 0, 0, 0},
  191. },*checked=&newmenu[NM_FONTTYPE],
  192.   *checkset;
  193.  
  194. /* Different width of box for each charset */
  195. UBYTE MaxWid,NumChars,CharsetNum=0;
  196.  
  197. /* Colors pens */
  198. UWORD fillpen=3,txtpen=1,poppen=2,filltxt=2,shine=2,darkpen=1;
  199.  
  200. /* Position of normal and minimized window */
  201. WORD Offset[]={0x7fff,0x7fff,0x7fff,0x7fff};
  202.  
  203. /* Function prototypes */
  204. BYTE setup();                                        /* Open window, ressources, font... */
  205. void cleanup(UBYTE *,WORD);                    /* Quit properly */
  206. void create_gadgets(void);                        /* Create the gadget using gadtools lib */
  207.  
  208. /**** Definition of the main loop: ****/
  209. int main(int argc, char *argv[])
  210. {
  211.     extern BOOL PopWin;                            /* True if the window is poped up at start */
  212.  
  213.     /* If no locale, use english as default */
  214.     if(LocaleBase = (struct Library *)OpenLibrary("locale.library", 38))
  215.         Translate_srings();
  216.  
  217.     /* These libraries are located in ROM. If it failed to open, it's   **
  218.     ** because we are attempting to run this programme on an old system */
  219.     if( !(GfxBase       = (struct GfxBase *)      OpenLibrary("graphics.library", MIN_VERSION)) ||
  220.         !(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",MIN_VERSION)) ||
  221.         !(GadToolsBase  = (struct Library *)      OpenLibrary("gadtools.library", MIN_VERSION)) ||
  222.          !(UtilityBase   = (struct Library *)      OpenLibrary("utility.library",  MIN_VERSION)) ||
  223.         !(KeymapBase    = (struct Library *)      OpenLibrary("keymap.library",   37)) )
  224.         cleanup(ErrMsg(MSG_BADOS),30);
  225.  
  226.     /* Open ze libraries */
  227.     if( (IconBase = (void *) OpenLibrary("icon.library",        MIN_VERSION)) &&
  228.         (CxBase   = (void *) OpenLibrary("commodities.library", 37L)) )
  229.         /* If the icon and commodities.library are present, and the **
  230.         ** programme failed to init as a commodity, it's probably   **
  231.         ** because it is already running, and user want to quit:    */
  232.     {    if( Init_commodity(argc,argv)==FALSE )
  233.             cleanup(0,0);
  234.     } else {
  235.         /* If commo. is not present, change menu "Hide" by "Next screen" */
  236.         newmenu[13].nm_Label = ErrMsg(MSG_NEXTSCR);
  237.         newmenu[13].nm_CommKey = "J";
  238.         newmenu[13].nm_UserData = (APTR)25;
  239.     }
  240.  
  241.     /* Same as gadget or menu text: */
  242.     newmenu[17].nm_Label=GadTxt[3];
  243.     newmenu[18].nm_Label=GadTxt[4];
  244.  
  245.     /* Init cycle font-type gadget text list and charset cycle gad */
  246.     for(checkset=&newmenu[NM_CHARSET], X=6; X<7+NUM_CHARSET+4; X++,checkset++)
  247.     {
  248.         if(X==GT-1) X+=2,checkset=&newmenu[2];
  249.         GadTxt[ X ]=checkset->nm_Label;
  250.     }
  251.  
  252.     /* No ASL or diskfont library, no font requester */
  253.     if( !(DiskfontBase = (struct Library *)OpenLibrary("diskfont.library",0)) ||
  254.         !(AslBase = (struct Library *)OpenLibrary("asl.library",MIN_VERSION)) ) {
  255.         newmenu[NM_FONTTYPE+2].nm_Flags |= NM_ITEMDISABLED;
  256.         GadTxt[GT+3] = 0;
  257.     }
  258.  
  259.     /* For temporary font measurement */
  260.     InitRastPort( &RPT );
  261.  
  262.     /* Get access to the frontmost screen */
  263.     screen = IntuitionBase->ActiveScreen;
  264.     font = screen->RastPort.Font;
  265.  
  266.     /* Initial charset displayed */
  267.     if(CharsetNum<1 || CharsetNum>NUM_CHARSET) Init_charset(font);
  268.     checkset=&newmenu[CharsetNum+NM_CHARSET-1];
  269.     checkset->nm_Flags |= CHECKED;
  270.  
  271.     if(PopWin)
  272.         /* If setup failed at start (font too big) */
  273.         if(setup()) Handle_menu(113L);
  274.  
  275.     handle_input();
  276. }
  277.  
  278. /*** Setup the window, return 1 if init failed ***/
  279. BYTE setup()
  280. {
  281.     struct DrawInfo *di;
  282.  
  283.     /* Get the screen's visual information data */
  284.     if( !(vi = (void *) GetVisualInfoA( screen,NULL )) )
  285.         cleanup(ErrMsg(MSG_SCREENLOCK),30);
  286.  
  287.     BoxTags[1]=(ULONG)vi;
  288.  
  289.     /* Adjust the pen numbers to what the screen uses */
  290.     if( di = (void *)GetScreenDrawInfo(screen))
  291.     {
  292.         /* Get a copy of the correct pens for the screen */
  293.         fillpen = di->dri_Pens[FILLPEN];
  294.         txtpen  = di->dri_Pens[TEXTPEN];
  295.         filltxt = di->dri_Pens[FILLTEXTPEN];
  296.         shine   = di->dri_Pens[SHINEPEN];
  297.         darkpen = di->dri_Pens[SHADOWPEN];
  298.         poppen  = 3; if(txtpen==3) poppen=fillpen;
  299.  
  300.         /* This one is only available on system V39+ */
  301.         if(di->dri_Version>=2) MenuTags[1] = di->dri_Pens[BARDETAILPEN];
  302.         FreeScreenDrawInfo(screen,di);
  303.     }
  304.     /* Those string can be set to NULL, to reduce interface's width */
  305.     GadTxt[1]=newmenu[1].nm_Label;
  306.     GadTxt[2]=newmenu[NM_CHARSET-1].nm_Label;
  307.     if(VertSort) newmenu[21].nm_Flags |= CHECKED;
  308.     else         newmenu[21].nm_Flags &= ~CHECKED;
  309.  
  310.     /* Build the menu-strip and compute menu items size */
  311.     if( !(menu = (void *) CreateMenusA(newmenu, MenuTags)) ||
  312.         !LayoutMenusA(menu, vi, NULL) )
  313.        cleanup(ErrMsg(MSG_ERRLAYOUT),30);
  314.  
  315.     SetFont(&RPT,font);
  316.     /* Read the size of the 256 characters of the current font, **
  317.     ** and compute the maximal width of the box chars           */
  318.     NumChars = CharsetNum==1 ? 32 : CharsetNum == 2 ? 28 : 24;
  319.     {
  320.         register WORD I;
  321.         register UBYTE *W;
  322.         for(I=0,W=CharWid,MaxWid=0; I<256; I++,W++) {
  323.             *Char = I;
  324.             *W = TextLength(&RPT,Char,1);
  325.  
  326.             /* Compute the width of each box: */
  327.             switch( CharsetNum )
  328.             {
  329.                 case 3: if(I>=127 && I<160) break;
  330.                 case 2: if(I<32) break;
  331.                 case 1: if(MaxWid < *W+6) MaxWid=*W+6;
  332.             }
  333.         }
  334.     }
  335.  
  336.     /* Some important font size-depending values */
  337.     Font_height = font->tf_YSize+4;
  338.     SetFont(&RPT,screen->RastPort.Font);
  339.  
  340.     /* Measure length of strings */
  341.     for(X=0; X<4; X++)
  342.     {
  343.         static char Len[]={15,10,10,10}, offs[]={4,2,1,5};
  344.         register BYTE *str = GadTxt[ offs[X] ];
  345.         Wid[ X ] = TextLength(&RPT,str,strlen(str))+Len[X];
  346.     }
  347.     CyCLen = Meas_table(GadTxt+6)+30;
  348.     CyFLen = Meas_table(GadTxt+GT+1)+30;
  349.     /* If "Font" text length is shorter than "String", right aligns text */
  350.     if(FtLen < VaLen) FtLen=VaLen;
  351.  
  352.     for(X=1;;) {
  353.         /* Computes the width of our window */
  354.         new_window.Width = xfin = MaxWid*NumChars+20;
  355.  
  356.         /* Does the width of the window fit in the screen? */
  357.         if(xfin > screen->Width)
  358.         {
  359.             /* No! force the window width */
  360.             MaxWid = (screen->Width-20) / NumChars;
  361.             continue;
  362.         }
  363.  
  364.         if(X==0) break;
  365.         /* Is there place for gadgets? */
  366.         if( (X=FtLen + CyCLen + CyFLen)+30 > xfin)
  367.             MaxWid=(X + 10) / NumChars + 1, X=0;
  368.         else break;
  369.     }
  370.  
  371.     /* Try to optimize rendering of layout */
  372.     X=new_window.Width-ChrLen-FtLen-40; xdeb = X/3; Layout = LARGE_LAYOUT;
  373.     if(CBLen < X - CyCLen - CyFLen)
  374.         if(CyCLen <= xdeb && CyFLen <= xdeb)
  375.             CBLen = CyCLen = CyFLen = xdeb;
  376.         else /* One of cycle gadget is too wide, adjust just copy/paste gad: */
  377.             CBLen = X - CyCLen - CyFLen;
  378.     else /* Expand just cycle gadgets */
  379.         if(X + 10 >= CyCLen + CyFLen)
  380.             CyCLen=CyFLen= (X + 10) / 2, Layout = MIDDLE_LAYOUT;
  381.         else /* Not enough place for both gadget's caption & gadget */
  382.             CyCLen=CyFLen=(X+10+ChrLen)/2, ChrLen=0,
  383.             GadTxt[2]=NULL, Layout = SMALL_LAYOUT;
  384.  
  385.     /* Setup normal and minimized position of main window */
  386.     new_window.TopEdge  = Adjust_pos(Offset[1],screen->Height,
  387.     new_window.Height   = Font_height*8+4*screen->Font->ta_YSize+41 );
  388.     new_window.LeftEdge = Adjust_pos(Offset[0],screen->Width,xfin);
  389.  
  390.     /* Title of the window is the name of our font */
  391.     new_window.Title    = font->tf_Message.mn_Node.ln_Name;
  392.     new_window.Screen   = screen;
  393.  
  394.     /* Init the position and the size of the minimized window */
  395.     ZoomData[0] = Adjust_pos(Offset[2],screen->Width,
  396.     ZoomData[2] = TextLength(&screen->RastPort,new_window.Title,strlen(new_window.Title))+100);
  397.     ZoomData[1] = Adjust_pos(Offset[3],screen->Height,
  398.     ZoomData[3] = screen->BarHeight+1);
  399.  
  400.     /* If this call failed, the font is VERY too much big! */
  401.     if( !(window = (void *) OpenWindowTagList(&new_window,WinTags)) )
  402.         /* If ASL is avaible, show a requester to change the font: */
  403.         if( avert(ErrMsg(MSG_FONTREALLYBIG)) && AslBase )
  404.             return TRUE;
  405.         else cleanup(0,0);    /* Game over! */
  406.  
  407.     /* Signal bit, to process events from the window */
  408.     sigwin = 1 << window->UserPort->mp_SigBit;
  409.     SetMenuStrip(window, menu);    /* Attach the menu to the window */
  410.     Init_helpwin(window);            /* Draws information bar */
  411.     create_gadgets();                    /* Creates all gadgets */
  412.     return FALSE;
  413. }
  414.  
  415. /*** Desallocate all ressources: ***/
  416. void cleanup(UBYTE *msg,WORD err)
  417. {
  418.     extern APTR FR;
  419.     extern void *catalog;
  420.  
  421.     if (msg)            puts(msg);
  422.     if (window)    {
  423.         /* Save the positions of the window before to close it */
  424.         CopyMem(&window->LeftEdge,Offset,2*sizeof(WORD));
  425.         CopyMem(ZoomData,Offset+2,2*sizeof(WORD));
  426.         /* Now we can restore it's place if it will be reopen */
  427.         ClearMenuStrip(window);
  428.         CloseWindow(window);
  429.         window=NULL; sigwin=0;
  430.     }
  431.  
  432.     /* These two functions can take a NULL, but let's stay consistent */
  433.     if (glist) FreeGadgets(glist);    glist=0;
  434.     if (vi) FreeVisualInfo(vi);        vi=0;
  435.     if (menu) FreeMenus(menu);            menu=0;
  436.  
  437.     if (err<0) return;
  438.     Free_commodity();
  439.     if (FR)                    FreeAslRequest(FR);
  440.     if (newfont)            CloseFont(newfont);
  441.     if (catalog)            CloseCatalog(catalog);
  442.     if (clipdev)            CBClose(clipdev);
  443.     if (CxBase)                CloseLibrary(CxBase);
  444.     if (AslBase)            CloseLibrary(AslBase);
  445.     if (IconBase)            CloseLibrary(IconBase);
  446.     if (KeymapBase)        CloseLibrary(KeymapBase);
  447.     if (LocaleBase)        CloseLibrary(LocaleBase);
  448.     if (DiskfontBase)        CloseLibrary(DiskfontBase);
  449.     if (GadToolsBase)        CloseLibrary(GadToolsBase);
  450.     if (IntuitionBase)    CloseLibrary(IntuitionBase);
  451.     if (GfxBase)            CloseLibrary(GfxBase);
  452.     exit(err);
  453. }
  454.  
  455. /*** Draw the table of characters ***/
  456. void Draw_ASCIIChart( void )
  457. {
  458.     extern   WORD OldX;
  459.     register WORD i,x,y;
  460.  
  461.     /* Initial bevel box, which will be copied 256 times */
  462.     SetFont(RP,font); SetABPenDrMd(RP,0,0,JAM1); BoxTags[2] = TAG_DONE; OldX=0;
  463.     RectFill(RP,xdeb,ydeb,xdeb+MaxWid,ydeb+Font_height);
  464.     DrawBevelBoxA(RP,xdeb,ydeb,MaxWid,Font_height,BoxTags);
  465.  
  466.     /* Exponential copy (very fast :-) */
  467.     for(x=MaxWid,i=xdeb+x,y=window->Width-10; i<xfin; ) {
  468.         ClipBlit(RP,xdeb,ydeb,RP,i,ydeb,x,Font_height,0xC0);
  469.         i+=x; x<<=1; if(i+x>y) x=y-i;
  470.     }
  471.  
  472.     for(x=Font_height,i=ydeb+x; i<yfin; i+=x,x<<=1)
  473.         ClipBlit(RP,xdeb,ydeb,RP,xdeb,i,y,x,0xC0);
  474.  
  475.     SetAPen(RP,txtpen);
  476.     /* Character in each box */
  477.     for(i=CharsetNum==1?0:32,x=xdeb,y=ydeb+font->tf_Baseline+2;
  478.         i<256; i++, VertSort ? (y+=Font_height):(x+=MaxWid) )
  479.     {
  480.         if( x>=xfin ) x=xdeb, y+=Font_height;
  481.         if( y>=yfin ) x+=MaxWid, y-=Font_height<<3;
  482.         /* 127th char for Amiga charset isn't displayed */
  483.         if(CharsetNum==3 && i==127) { i=159; continue; }
  484.         *Char = i;
  485.         Move(RP,x+(MaxWid-CharWid[i]>>1),y);
  486.         Text(RP,Char,1);
  487.     }
  488. }
  489.  
  490. /*** Create the gadgets associated with the window ***/
  491. void create_gadgets()
  492. {
  493. #ifdef    __GNUC__
  494. #    define tmpgad        ((struct Gadget *)RP)
  495. #else
  496.     struct Gadget *tmpgad;
  497. #endif
  498.     static UBYTE  goff[]={3,0,0,5,4}, toff[]={0,3,4,1,2};
  499.     extern UBYTE *StrBuf;
  500.     struct NewGadget ng;
  501.     UWORD  top,I;
  502.  
  503.     /* Init some variables */
  504.     top = window->BorderTop + 1;
  505.     gad = (void *) CreateContext(&glist);
  506.     RP  = &screen->RastPort;
  507.  
  508.     ng.ng_TextAttr = screen->Font;
  509.     ng.ng_VisualInfo = vi;
  510.     I = Layout==LARGE_LAYOUT ? CBLen:(CBLen<<1)+10;
  511.  
  512.     /* The NewGadget stucture is not modified by any Gadget creation call, so   **
  513.     ** you'll only need to change information that actually needs to be changed */
  514.     ng.ng_Flags      = PLACETEXT_LEFT | NG_HIGHLABEL;
  515.     ng.ng_GadgetText = GadTxt[5];
  516.     ng.ng_LeftEdge   = VaLen+10;
  517.     if(ng.ng_LeftEdge+10 > FtLen) ng.ng_LeftEdge=FtLen+10;
  518.      ng.ng_Width      = window->Width - 20 - I - ng.ng_LeftEdge - (
  519.     ng.ng_Height     = VaLen = screen->Font->ta_YSize+6);
  520.     ng.ng_TopEdge    = top+5;
  521.     ng.ng_GadgetID   = 10;
  522.  
  523.     /** String gadget **/
  524.     tmpgad = gad = (void *) CreateGadget(STRING_KIND, gad, &ng, GTST_MaxChars,50,TAG_DONE);
  525.     StrBuf = sti(gad)->Buffer;
  526.  
  527.     /** Name of the charset displayed in the cycle gad: **/
  528.     CycleTags[3]=CharsetNum-1;
  529.  
  530.     /** Creates the 5 gadgets shortcut (Sorry for this very crap code...) **/
  531.     ng.ng_LeftEdge -= 10;
  532.     ng.ng_Flags     = PLACETEXT_IN;
  533.     for(I=0; I<5; I++)
  534.     {
  535.         ng.ng_GadgetID    = I;
  536.         ng.ng_GadgetText  = GadTxt[ toff[I] ];
  537.         if(I!=2 || Layout!=LARGE_LAYOUT) ng.ng_LeftEdge+=ng.ng_Width+10; else goto next_row;
  538.         ng.ng_Width       = Wid[ goff[I] ];
  539.  
  540.         if(I==3) { ng.ng_Flags = PLACETEXT_LEFT | NG_HIGHLABEL; ng.ng_LeftEdge = FtLen+10;
  541.                    if( Layout != LARGE_LAYOUT )
  542.         next_row:  ng.ng_Height -= 2, top = (ng.ng_TopEdge += ng.ng_Height+6); }
  543.  
  544.         if(I==4) ng.ng_LeftEdge += ChrLen;
  545.  
  546.         tmpgad = (void *) CreateGadgetA(I<=2 ? BUTTON_KIND:CYCLE_KIND, tmpgad, &ng,
  547.                                 I==4 ? CycleTags : I==3 ? FontTags:NULL);
  548.  
  549.         if(I==1) copy_gad=tmpgad; if(I==2) paste_gad=tmpgad;
  550.  
  551.         /* If a ressource isn't available, disable the corresponding gadget */
  552.         if(GadDisable & (1<<I)) tmpgad->Flags |= GADGDISABLED;
  553.     }
  554.  
  555.     /*    Now we're ready to add the Gadget list. Quit if the final Gadget pointer is **
  556.     ** NULL - this means that one of the Gadget allocations failed. If it exists,  **
  557.     ** add it to the window and refresh, then add the new GT_RefreshWindow() call. */
  558.     if (!tmpgad)
  559.         cleanup(ErrMsg(MSG_ERRGADGET),30);
  560.  
  561.     /** Refresh everything **/
  562.     AddGList(window, glist, (UWORD)-1, (UWORD)-1, NULL);
  563.     RefreshGList(glist, window, NULL, (UWORD)-1);
  564.     GT_RefreshWindow(window, NULL);
  565.     RP=window->RPort;
  566.  
  567.     /** Draw the ASCII table **/
  568.     xdeb = 10;            ydeb = top+ng.ng_Height+5;
  569.     xfin -= 10;            yfin  = ydeb+Font_height*8;
  570.     Draw_ASCIIChart();
  571. }
  572.